=begin rdoc
Definition File for 1129-reduced-initset.evl eventset

Author::    Matthias Woehrle  (mailto:matthias.woehrle@tik.ee.ethz.ch)
Copyright:: Copyright (c) 2008 ETH Zurich
License::   

TODO:

MISSING:

=end
$: << File.expand_path(File.dirname(__FILE__) + "/../lib")
#would like to use this but does not work (simple csv writing probably does not require this anyway)
#require 'fastercsv'
sourcepath =  File.expand_path("/home/woehrlem/devel/tossim/")


require "rupeas"


Rupeas.new do

Type :senddone do
 with :name =>:seqNo, :fieldtype=> :periodic, :range => 0..255, :notification => :error
 with :name =>:origin, :fieldtype => :integer, :range => 0..100,:notification => :error
 with :name =>:destination, :fieldtype => :integer, :range => 0..100, :notification => :warning
 with :name =>:nodeid,:fieldtype=> :integer, :range => 0..100,:notification => :error
 with :name =>:time, :fieldtype => :float, :notification => :warning 
end

Type :receive do
 with :name =>:seqNo, :fieldtype=> :periodic, :range => 0..255, :notification => :error
 with :name =>:origin, :fieldtype => :integer, :range => 0..100,:notification => :error
 with :name =>:destination, :fieldtype => :integer, :range => 0..100, :notification => :warning
 with :name =>:nodeid,:fieldtype=> :integer, :range => 0..100,:notification => :error
 with :name =>:time, :fieldtype => :float, :notification => :warning 
end

filename = 'medium.log'

all = loadlog(sourcepath + '/' + filename)
t=Time.new
monthdayhourmin = t.strftime("%y-%m-%d--%H%M")
csvfile = File.open('result-' + filename + '-' + monthdayhourmin + '.csv', 'w')
total_packets = 0
total_duplicates = 0
total_real_duplicates = 0
total_sent = 0
total0 = 0
total100 = 0
total_hop_counts = 0
csvfile.write("origin, arrived, arrived0, arrvied100, doubles, real doubles, unsuccessful, sent, unprocessed, hop_count, hop_count0, hop_count100\n")


r = File.open('logfile-' + filename + '-' + monthdayhourmin + '.txt', 'w')
[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,0,43,44,45,46,100,48,49,50,51,52,53,
  54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79].each do |origin|
#[13, 14, 15].each do |origin|
  origin_sent = 0
  origin_packets = 0
  origin0 = 0  
  origin100 = 0  
  origin_duplicates = 0
  origin_real_duplicates = 0
  other_length = 0
  origin_unsuccesful = 0
  origin_hop_counts = 0
  origin0_hop_counts = 0
  origin100_hop_counts = 0    
  
  if all[:origin=>origin].length > 0
    r.write "------------\nProcessing #{all[:origin=>origin].length} events for origin #{origin}\n------------\n"
    originfiltered = all[:origin=>origin]
     #p all.values(:seqNo)
      puts "------------\nProcessing #{originfiltered.length} events for origin #{origin}\n"

      all.values(:seqNo).each do |seqNo|
#      puts "------------\nProcessing #{originfiltered[:seqNo=>seqNo].length} events for origin #{origin} and sequence Number #{seqNo}\n"
       
       routestart_temp = originfiltered[:seqNo=>seqNo].predicate(1){|send| send[:origin] == send[:nodeid] and send[:type] == :senddone}
       routestart = transform(routestart_temp, :merge, 1) do |e1|
            {
              :type => :transmission,
              :nodeid => e1[:nodeid],
              :destination => e1[:destination],
              :seqNo => e1[:seqNo],
              :origin => e1[:origin],
              :time => e1[:time],
              :path => e1[:nodeid].to_s,
              :hop_count => 0.5
            }
            end
            
       packet_starts = routestart[:type=>:transmission].length
       
#       r.write originfiltered[:seqNo=>seqNo].to_s
              
       resultset = routestart.iterative do |iteration|
          temp = iteration.predicate(2) {|e1, e2| e1[:origin] == e2[:origin] and  e1[:origin] == e2[:origin] and ((e1[:type] == :transmission and \
          e2[:type] == :receive and e1[:destination] == e2[:nodeid]) or (e1[:nodeid] == e2[:nodeid] and
          e1[:type] == :transmission and e2[:type] == :senddone))
          }
          iteration.transform(temp, :merge, 2) do |e1, e2|
          {
            :nodeid => e2[:nodeid],
            :type => :transmission,
            :origin => e1[:origin],
            :destination => e2[:destination],
            :seqNo => e1[:seqNo],
            :time => e2[:time],
            :path => (e1[:path].to_s + '-' + e2[:nodeid].to_s),
            :hop_count => e1[:hop_count] + 0.5
          }
         end
       end
       
       transmission = resultset[:type=>:transmission]

       transmissions_to_0 = transmission[:nodeid=>0]
       transmissions_to_100 = transmission[:nodeid=>100]
       
       
              
       success0   =     transmissions_to_0.length
       success100 =     transmissions_to_100.length
       success = success0 + success100
       
       temp0_hop = 0
       if success0 > 0
         transmissions_to_0.each {|trans0_event| temp0_hop+= trans0_event[:hop_count]} 
         origin0_hop_counts += temp0_hop / success0
       end

       temp100_hop = 0
       if success100 > 0
         transmissions_to_100.each {|trans100_event| temp100_hop+= trans100_event[:hop_count]} 
         origin100_hop_counts += temp100_hop / success100
       end
       
       if success0 > 0 and success100 > 0
         origin_hop_counts += (temp0_hop + temp100_hop)/2
       else #either only one carries a value or both are 0
         origin_hop_counts += (temp0_hop + temp100_hop)
       end
       
       unsuccesful_routing = transmission - transmissions_to_0 - transmissions_to_100
       
       origin_unsuccesful += unsuccesful_routing.length
       
       other_packets = resultset[:type=>:senddone].union(resultset[:type=>:receive])
       other_length += other_packets.length
       
       r.write("Others" + other_packets.to_s + "\n") if other_packets.length > 0
              
       if packet_starts > 0
         total_sent += 1
         origin_sent += 1
         if success == 0
           r.write("Unsuccessful and failed" + unsuccesful_routing.to_s + "\n") if unsuccesful_routing.length > 0
         else #success >0
           r.write("Unsuccessful, but recovered" + unsuccesful_routing.to_s + "\n") if unsuccesful_routing.length > 0
           total100 += 1 if success100 > 0
           total0 += 1 if success0 > 0
           total_packets += 1 if success > 0
           origin_packets += 1
           origin100 += 1 if success100 > 0
           origin0 += 1 if success0 > 0

           if success > 1
            origin_duplicates += 1
            total_duplicates += 1
            transmission.remove_key(:time)
            match = true
            ref_event = nil
            transmission.each do |event|
              ref_event || ref_event = event
              if event != ref_event
                match = true
                break
              end
            end
            if match == false
              origin_real_duplicates += 1
              total_real_duplicates += 1
              r.write("Duplicates" + transmission.to_s + "\n")
            else
             r.write("Fake duplicates" + transmission.to_s + "\n")             
            end
          end
         end
       else 
         r.write "\nGhost packet for #{origin}/#{seqNo}\n" if success > 0
       end
       total_hop_counts += origin_hop_counts
       
    end
#      r.write "Yield for origin #{origin} is #{origin_packets.to_f/origin_sent}\n"
#      r.write "Duplicate rate for origin #{origin} is #{origin_duplicates.to_f/origin_sent}\n"
      origin_packets_fixed = origin_packets
      origin_packets_fixed += 1 if origin_packets_fixed == 0
      origin0_fixed = origin0
      origin0_fixed += 1 if origin0_fixed == 0
      origin100_fixed = origin100
      origin100_fixed += 1 if origin100_fixed == 0


      csvfile.write(origin.to_s + ',' + origin_packets.to_s + ',' + origin0.to_s + ',' + origin100.to_s + ','  + origin_duplicates.to_s +  ','  + origin_real_duplicates.to_s + ',' + origin_unsuccesful.to_s + ',' + origin_sent.to_s + ',' + other_length.to_s  + ',' + (origin_hop_counts/origin_packets_fixed).to_s  + ',' + (origin0_hop_counts/origin0_fixed).to_s  + ',' + (origin100_hop_counts/origin100_fixed).to_s + "\n")

  end

end
  r.write "\nSummary\n--------------------\n"
  r.write "\nTotal Yield is #{total_packets.to_f/total_sent}\n"
  r.write "Duplicate rate is #{total_duplicates.to_f/total_sent}\n"   
  r.write "Real Duplicate rate is #{total_real_duplicates.to_f/total_sent}\n"        
  r.write "To sink 0, #{total0.to_f/total_packets} were sent, to 100 #{total100.to_f/total_packets}\n"        
  r.write " #{total_hop_counts.to_f/70} average hop_count\n"          
csvfile.close
r.close 
end
